_ostree_kernel_args_replace_take: don't leak when replacing
authorSimon McVittie <smcv@debian.org>
Sat, 29 Oct 2016 20:31:18 +0000 (21:31 +0100)
committerAtomic Bot <atomic-devel@projectatomic.io>
Sun, 30 Oct 2016 21:37:37 +0000 (21:37 +0000)
If !existed, then we add arg to kargs->order, where it will be freed
by that array's free-function. However, if the kernel argument did
already exist, we have to either free arg ourselves (and make sure
the old key is what appears in the hash table), or do a linear search
on kargs->order to replace the old key with the new.

Leak found by valgrind memcheck.

Signed-off-by: Simon McVittie <smcv@debian.org>
Closes: #559
Approved by: cgwalters

src/libostree/ostree-kernel-args.c

index 4c9ff147db241b5cd957a55a592025fbd5902bde..ec189fc191a01239654c690a6919a28add7f717f 100644 (file)
@@ -87,12 +87,21 @@ _ostree_kernel_args_replace_take (OstreeKernelArgs   *kargs,
   gboolean existed;
   GPtrArray *values = g_ptr_array_new_with_free_func (g_free);
   const char *value = split_keyeq (arg);
+  gpointer old_key;
 
-  existed = g_hash_table_remove (kargs->table, arg);
-  if (!existed)
-    g_ptr_array_add (kargs->order, arg);
   g_ptr_array_add (values, g_strdup (value));
-  g_hash_table_replace (kargs->table, arg, values);
+  existed = g_hash_table_lookup_extended (kargs->table, arg, &old_key, NULL);
+
+  if (existed)
+    {
+      g_hash_table_replace (kargs->table, old_key, values);
+      g_free (arg);
+    }
+  else
+    {
+      g_ptr_array_add (kargs->order, arg);
+      g_hash_table_replace (kargs->table, arg, values);
+    }
 }
 
 void